from vec3 import Vec3

class World:
    def __init__(self):
        self.bodies = []
        self.visualizers = []

        self.gravity = Vec3(0,-1,0)
        self.groundHeight = 0
        self.groundFriction = 1

    def tick(self, dt):
        for body in self.bodies:
            for pm in body.pointMasses:
                pm.applyForce(self.gravity * pm.mass)
            body.tick(dt)
            body.updateCollision()

        for body in self.bodies:
            for pm in body.pointMasses:
                if pm.pos.y < self.groundHeight:
                    
                    pm.pos.y = self.groundHeight
                    pm.vel.y *= -0.5

                    pm.applyForce(pm.vel * Vec3(1,0,1) * -self.groundFriction)

                for targetBody in filter(lambda b: b != body, self.bodies):
                    if targetBody.testCollision(pm):
                        targetPm = targetBody.closestPointMassTo(pm.pos)
                        targetPm.vel, pm.vel = pm.vel, targetPm.vel
                        targetPm.vel *= 0.5
                        pm.vel *= 0.5
                        
                        targetBody.reactCollision(pm)
                        body.updateCollision()
                        targetBody.updateCollision()
    
    def render(self):
        for visualizer in self.visualizers:
            visualizer.renderWorld(self)
